DDS周波数特性測定装置
(参考文献) PICで楽しむUSB機器(改定新版) 後閑哲也 著 技術評論社 2011
9
DDS(ダイレクト・デジタル・シンセサイザー)に、PC入力による周波数設定値をシリアルで送って掃引し、オーディオ 〜 中波程度の各周波数の正弦波を連続的に出力し、被測定物からの入力を対数変換してdBの数値とし、USB(CDCクラス)でパソコンに送り、周波数−dBのグラフを表示する。 使用している部品(DDS: AD9851、ログアンプ: AD8307)は
やや過剰品質気味だが、他に代替品が無いので文献に従ってこれらを用いたが、結果的にはコンパクトに作ることができた。
パソコン画面のソフトは、マイクロソフトが無償配布しているVB(ビジュアル・ベーシック)で作成し、コントロール画面で周波数範囲(上限・下限)、分解能、測定開始等を入力し、自動的に現れるグラフィック画面で 片対数目盛りの周波数−dB のグラフをリアルタイムで表示し、また データを保存(CSV形式)できるようにする。
1. ハードウエアと マイコンのプログラム:
DDSとして 代表的な AD9851(フラット、28p、0.65mmピッチ、電源5V)を DIP変換基板に付けて使用した。(*
変換基板への半田付けは、低融点はんだを用い、フラックスに漬けたソルダーウィックで吸い取る) これは、制御方法をシリアルに設定した後、パソコンからの 40ビットの周波数設定信号(内、32ビットが周波数値、8ビットが他の制御値)を受けて、100MHz以上の一定出力の正弦波(または方形波)を出力できる。ここでは、5VPICマイコン(PIC18F2550)のソフト制御なので速度を上げることができず、オーディオ周波数
+ α 程度に限定して、出力電圧をできるだけ一定にした正弦波を作ることにする。(この装置の測定範囲は、10Hz 〜 数MHz)
(* 単純な信号発生源とするならば、DDSを用いて数十MHzは容易に作る事ができる。)
DDSの出力部には、NJU4580D(汎用HiFiオペアンプ)の代わりに、もう少し高周波側で出力特性が一定になるように
NJM2137D(広帯域 200MHz)を用いた。 正弦波出力を±に振るために、−5V電源を
TC7662B(チャージポンプ DC-DCコンバーター)によって供給した。
+5V電源はノイズ除去フィルタを入れてUSBから取った。(全体で約150mA、DDSのICは少し発熱する)
被測定物からの入力は、ログアンプ(対数アンプ、AD8307、入力500MHzまで直線性良く一定出力)で受け、入力電圧レベルを dBレベルに変換し、さらにその出力を PICマイコンのアナログ端子で受け、AD変換により数値化してパソコンへ送り、作成したパソコン内ソフトによってグラフ化した。 低周波側の下限は、ログアンプ出力で接地されているパスコン(2.2μF*)によって決まる。
(** ログアンプは dBスケールの電界強度計、騒音計などにそのまま用いることができる。また、整流後の
DC入力の対数変換ならば、シリコンダイオードの特性を生かしても近似的には可能
→ (参照)湿度計のヘッド)
DDS ICの AD9851BRSの (D0、D1、D2)=(H、H、L)に固定した状態で、W_CLK、FQ_UDにパルス1個を与えると、シリアルモードになる。 1つの シリアル制御信号は40ビットで、
W0 〜 W31: 周波数データ(32ビット)、 W32: =1で クロック×6(発振 24MHz×6=144MHz)、 (W33=0)、 W34: =0で 省電力モードにしない、 W35〜39:
位相データ(360度を32分割)、となる。 周波数は、この32ビットの分割(0
〜 232 = 4294967296)で得られ、144MHzの場合は、 設定できる周波数の最小分解能
= 144000000/4294967296 = 0.0335 Hz になるので、
∴ 出力周波数 = 0.0335 × (W0〜31の設定値) となる。 (* float は、4バイト 浮動小数型変数: ±10-37 〜 ±1038)
マイコンプログラムでは、CDCクラス(USB Device - CDC - Basic Demo)を雛形として PIC18F2550 を用いる。(他の割込みが無いので問題なく使える。)
ヘッダーファイルの HardwareProfile.h を修正し、1.電源供給方法の検出、クロック周波数(48MHz)、 2.DDS用I/Oピンの指定、をあらかじめ設定して、プロジェクトに取り込む。
( 注) プロジェクト構成の usb device.c は、ビルドすると、ミスマッチエラーが出るので、文献のCDより
USB_Book\Microchip\USB から usb_device.c (114kB)をフォルダに移植した。バージョン不明)
(ハードウェアプロファイル)
ユーザーアプリ・プログラムでは、初期設定の後、メインループでは USBの接続完了、USB状態のLED表示のみで、ProcessIO()に飛ぶ。
ProcessIO()では、USB受信+周波数設定出力、 入力のAD変換+USB送信などのメイン処理を行うために、PCとマイコンの間に以下の規則を定める。
0: 接続の確認: PC → マイコン ・・・ 0x30、 マイコン → PC ・・・ 確認の応答 「OK ¥0(=0x00)」 を返す
1: 周波数設定: PC → マイコン ・・・ 0x31 xxxxx ¥0 (xxxxx : 周波数設定値)、 マイコン → PC ・・・ (なし)
・ atof 関数は 小数型文字列を
浮動小数(float)に変換、 math.h に含まれる
2: 計測の要求: PC → マイコン ・・・ 0x32、 マイコン → PC ・・・ チャンネル1、2の信号レベル値を 「CH0=±xx.x△△CH1=±yy.y\r\n\0」 という文字列で返す
・ ftostring 関数は
プログラム中に作成しているもので、浮動小数値を文字列に変換: ftostring(整数、小数、データ、バッファ)
PC からの 0x30 などの最後の1文字 0 、1、2 (= input_buffer[0] )で、switch 文により case 0、1、2 に振り分け、それぞれの処理をする。 case 2 の場合は、ログアンプからの対数アナログ入力を A/D変換し、演算を加えて、データを PCに送る。
スイープ動作では、周波数設定値ごとに 装置の CH0、1のデータを受け取り、PCグラフィックの描画を行う、というサイクルを、計測範囲が終了するまで繰り返す。
(ユーザーアプリ部)
● ソース:
2. 制御ウィンドウと グラフィックの PCプログラム:
マイクロソフトが無償配布している ビジュアル・ベーシック(VB)(あるいは、VC++、VC# ・・・ リビルド可)を用いて、 (1) 制御ウィンドウと、(2) グラフィック・ウィンドウ を作成する。
ウィンドウの原型枠は初めから用意されていて、@ フォ−ムデザイン([デザイン]、あるいは、.Desiner.vb)として サイズ、ボタンやラベル(文字・数字)などを付け加え、基本フォームとする。 それから A ユーザーアプリ(.vb)としてマイコンとのUSB通信や制御法、表示法などの具体的な機能を与える。
(@ は、VBのツールボックス、プロパティーなどにより、ウィンドウを加工するときに自動的に創成される。VB付属の例題(チュートリアル)参照。)
作成中のプログラムは、ビルド(<デバッグ)してからデバッグすると制御ウィンドウ、グラフィックが現れ、機能をチェックしながら作成することができる。
* 配布元: Visual Basic 2010 Express: http://www.microsoft.com/ja-jp/dev/express/default.aspx
(マイコン−PC 間の CDC(文字通信)バッファ) 通信: 1バイト
= 8 bit
(ユーザーアプリ部)
● COMポート用 Windows API 関数: USB−CDCデバイスを PCに接続すると、標準デバイスドライバとなって、自動的にCOMポートが追加される。COMポートの通信は、Windowsで用意されているAPI
関数で記述する。 この関数群を使うために、独立したモジュール Module1.vb が必要となり、そのまま ソリューションに追加する。
この通信条件のパラメータに、DCB構造体(デバイス制御用の情報を格納)と COMMTIMEOUTS構造体(送受信のタイムアウト時間の設定)が用いられ、これによって
COMポートを「ファイル」として操作することができる。
CreateFile: COMポートオープン、 戻り値( = hComm) = CreateFile(ファイル名(”COM1”などの文字列)、 オープン方法(&HC0000000
で 読み書き両用)、 共有モード(0 で共有しない)、 セキュリティー属性(IntPtr.Zero
で 不使用)、 既存ファイルの処理(&H3 で既存ファイルオープン)、 ファイルの属性(&H80
で 無し)、 テンプレートファイル(IntPtr.Zero で 不使用))、 戻り値:
成功:ハンドル値、失敗:−1
CloseHandle: COMポートクローズ、 戻り値 = CloseHandle(ポートのハンドル値(CreateFileで取得した指定ポート
= hComm))、 戻り値: 成功:False(0)、失敗:同じハンドル値
SetCommState: 通信条件の設定、 戻り値 = SetCommState(ポートのハンドル値、 DCB構造体ポインタ(=
stDCB))、 戻り値: 正常:0、 エラー:−1
* stDCB の内容: .DCBlength: 構造体のサイズ(規定値のまま)、 .BaudRate:
ボーレート(= 19200bps)、 .fBitFields: ビットごとに付けられた制御指定(ビットNo1:
1のときバイナリモード(1)、 2: 1のときパリティーチェック有り(0)、
3: 1のときCTS制御をする(0)、 4: 1のときDSRを監視制御(0)、 5、6:
DTRによるハンドシェイク(00で しない)、 7: 1のときDSRがオフのとき受信データを無視(0)、 8:
1のときXoff文字送信後も送信続ける(0)、 9: 1のときXoff文字受信後送信停止しXonで再開(0)、
10: 1のときバッファ空きでXoff、Xonを送信(0)、 11: 1のときパリティーエラー処理(0)、
12: 1のときヌル文字を破棄(0)、 13、14: RTSによるハンドシェイク指定(00)、
15: 1のときエラー発生により読み書き停止(0)、 16: 未使用(0) ・・・・ &H1(&H:16進数
で1) = 0000000000000001 )、 .ByteSize: データのビット数(7 or
8 のうち 8)、 .Parity: 0でパリティーなし、 .StopBits: 0で1ビット、 .XonChar:
Xon文字指定(規定値)、 .XoffChar: Xoff文字指定(規定値)、 など)
GetCommState: ポートの現在状態確認、 戻り値 = GetCommState(ポートのハンドル値、 DCB構造体ポインタ)、 戻り値: 成功:1、失敗:0
ReadFile: データ受信、 戻り値 = ReadFile(ポートのハンドル値(= hComm)、 受信バッファのポインタ(=
rDATA)、 受信バイト数(= 30、22等 ・・・ 多めに指定)、 受信完了バイト数(=
rLen ・・・ 実際に受信したバイト数)、 IntPtr.Zero(不使用))、 戻り値: 成功:1、失敗:0
WriteFile: データ送信、 戻り値 = WriteFile(ポートのハンドル値(= hComm)、 送信バッファのポインタ(=
wDATA)、 送信バイト数(= dLen)、 送信完了バイト数(= wLen)、 IntPtr.Zero(不使用))、 戻り値: 成功:1、失敗:0
SetCommTimeouts: タイムアウト時間設定、 戻り値 = SetCommTimeouts(ポートのハンドル値、 COMMTIMEOUTS構造体名)、 戻り値: 成功:1、失敗:0
(1) FreqAnalizer.vb:
(2) Graph1.vb、 Module1.vb:
● FreqAnalizer(ユーザーアプリ部(FreqAnalizer.vb、 Graph1.vb、 Module1.vb)のみ): * プロジェクト一式は、参考文献付属のCD参照
● フィルタの測定結果 (入力(青線)を 短絡時 0dBに調整): (ただし、出力オペアンプはNJU4580D使用)
● グラフの横軸(周波数)の間隔を開ける:
曲線の周波数変化の詳細を見るために、FreqAnalizer.vbと
Graph1.vbの 両方の分割値を変更(6 → 2)して、片対数目盛りの間隔を開けた。 このとき、原点座標を 10kHzから描画するためにずらすため、G.TranslateTransform の x 値も変更(1
→ −924)した。 グラフ、ボタンの数字も直す。
(別フォルダにコピーして、VBのソリューション・エクスプローラーで名前を変更、ビルドし、bin
> Release > ファイル名(FreqAnalizer 2、3 など) のアイコンを デスクトップなどに貼って使用する。)
● 低周波で分解能を上げる:
プライベート・サブ関数: getDiff の設定値を変える。(10Hz
〜 1kHzまで) 原点座標は元に戻す。 下図は、オペアンプフィルター(NF(ノッチフィルター・50Hz、100Hz)、LPF(ローパスフィルター、50Hz)の測定例。
§ マイコンと パソコンとの関係から 示されること:
パソコンは、プログラムという名の”言葉”の集合体で、プログラムがいのちです。 マイコンも機能が特化されているとはいえ、フラッシュメモリに小規模の”言葉”を持っています。
そして、それぞれが発振器とCPUを持つ”独立した神状態”なので、上下関係をあらかじめ設定しておかなければ
システム全体として成り立ちません。 マイコン間の通信(I2C、SPI など)でも、”マスター(主人)”と”スレーブ(奴隷)”という関係があるように、USBではパソコンが圧倒的に”主人”で、パソコンと通信するマイコンは”奴隷”です。( ・・・ スペイン語では”主人”を”セニョール”と言う。 あまりマイコンに無理させると、文句が出る? ・・・
そりゃあないぜ、セニョール ・・・ )
神様と人間との関係もこのようです。 神は、「言葉の神」です。 人も、「神様に似せて造られました」。(創世記1:26) それゆえ、人は
唯一、言葉を語り、聞き、言葉で考える生き物です。DNAも 非常に精巧な”言葉”の集合体です。
もちろん、神様は「人格神」であり、意志を持っているので、規模においても、次元においても、とても
コンピュータとは比較になりませんが、言葉が内に満ちているという点で共通しています。
また、すべての人間にも、内側に「心の律法」(ローマ2:15)という”ROM”を生まれつき持っています。
USB通信の一番の特徴は、2線で通信し、軽量かつ(差動で信号をやり取りするので)ノイズに強いことですが、USB−CDC等の通信時に マイコンのほうが、常に、パソコンからの情報をチェックしていることが挙げられます。いわば、いつもパソコンに伺いを立てていることになります。 他の割り込みで、USB接続待ちが切れると、通信が途絶えてしまいます。
多くのUSB−CDC関係のプログラムのメインループでは、なんと、USB接続待ちだけで、実質的な作業はすべて processIO( ) で行います。 すなわち、”主人”からの指示(指示があっても無くても)を短い周期で定期的にチェックし、コマンドがあればいつでも即実行できるようにしています。 CDC(文字通信クラス)なので、通信はすべて 文字列 = 言葉で行います。 プログラムはその一点一画が欠落すると、まともに動きません。
神様は今も生きておられ、私たちに、言葉を語られるお方です。 御子イエス様は「神のことば」です。(ヨハネ1:1) また、「イエスのあかしは預言の霊です。」(黙示録19:10) 主の語りかけを受け取るために、私たちはいつも祈って、聞き耳を立てていなければなりません。 そして、神の言葉に聞き従う事が人にとってすべてであり、神の言葉こそが
すべてのことを成し遂げます。(イザヤ55:11)